package com.cheng.im.service.conversation.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cheng.im.common.bean.msg.ProtoMsgV1;
import com.cheng.im.common.constants.SeqConstants;
import com.cheng.im.service.common.eunms.ConversationErrorCode;
import com.cheng.im.service.common.eunms.ConversationTypeEnum;
import com.cheng.im.service.common.model.SyncReq;
import com.cheng.im.service.common.model.SyncResp;
import com.cheng.im.service.common.resp.CommonResult;
import com.cheng.im.service.conversation.domain.ImConversationSet;
import com.cheng.im.service.conversation.mapper.ImConversationSetMapper;
import com.cheng.im.service.conversation.model.req.AddConversationSetReq;
import com.cheng.im.service.conversation.model.req.DeleteConversationReq;
import com.cheng.im.service.conversation.model.req.PullConversationSet;
import com.cheng.im.service.conversation.model.req.UpdateConversationReq;
import com.cheng.im.service.conversation.model.resp.PullConversationSetResp;
import com.cheng.im.service.conversation.model.resp.UserData;
import com.cheng.im.service.conversation.service.ImConversationSetService;
import com.cheng.im.service.group.domain.ImGroup;
import com.cheng.im.service.group.service.ImGroupService;
import com.cheng.im.service.message.model.resp.LastMessageResp;
import com.cheng.im.service.message.service.ImMessageHistoryService;
import com.cheng.im.service.redis.seq.RedisSeq;
import com.cheng.im.service.redis.seq.WriteUserSeq;
import com.cheng.im.service.user.domain.ImUserData;
import com.cheng.im.service.user.service.ImUserDataService;
import com.cheng.im.service.util.SnowflakeIdWorker;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
* @author Cheng
* @description 针对表【im_conversation_set】的数据库操作Service实现
* @createDate 2025-01-09 08:19:12
*/
@Service
public class ImConversationSetServiceImpl extends ServiceImpl<ImConversationSetMapper, ImConversationSet>
    implements ImConversationSetService{

    @Resource
    RedisSeq redisSeq;
    @Resource
    WriteUserSeq writeUserSeq;
    @Resource
    ImUserDataService imUserDataService;
    @Resource
    ImMessageHistoryService imMessageHistoryService;
    @Resource
    ImGroupService imGroupService;
    @Resource
    SnowflakeIdWorker snowflakeIdWorker;

    @Override
    public String convertConversationId(Integer type, String fromId, String toId) {
        return type + "_" + fromId + "_" + toId;
    }

    @Override
    public void messageMarkRead(ProtoMsgV1.Message messageReadContend) {
        ProtoMsgV1.MessageRead messageRead = messageReadContend.getMessageRead();
        String toId = messageRead.getTo();
        if(messageRead.getConversationType() == ConversationTypeEnum.GROUP.getCode()){
            toId = messageRead.getGroupId();
        }

        String conversationId = convertConversationId(messageRead.getConversationType(),
                messageRead.getFrom(), toId);

        LambdaQueryWrapper<ImConversationSet> query = new LambdaQueryWrapper<>();
        query.eq(ImConversationSet::getConversationId, conversationId);
        query.eq(ImConversationSet::getAppId, messageReadContend.getAppId());
        ImConversationSet imConversationSetEntity = baseMapper.selectOne(query);

        if(imConversationSetEntity == null){
            imConversationSetEntity = new ImConversationSet();

            long seq = redisSeq.doGetSeq(messageReadContend.getAppId() + ":" + SeqConstants.CONVERSATION);

            imConversationSetEntity.setConversationId(conversationId);
            imConversationSetEntity.setFromId(messageRead.getFrom());
            imConversationSetEntity.setConversationType(messageRead.getConversationType());

            imConversationSetEntity.setReadedSequence(messageReadContend.getSequence());
            imConversationSetEntity.setToId(toId);
            imConversationSetEntity.setSequence(seq);
            baseMapper.insert(imConversationSetEntity);

            writeUserSeq.writeUserSeq(messageReadContend.getAppId(),
                    messageRead.getFrom(), SeqConstants.CONVERSATION, seq);
        }else{
            long seq = redisSeq.doGetSeq(messageReadContend.getAppId() + ":" + SeqConstants.CONVERSATION);
            imConversationSetEntity.setSequence(seq);
            imConversationSetEntity.setReadedSequence(messageReadContend.getSequence());
            baseMapper.readMark(imConversationSetEntity);
            writeUserSeq.writeUserSeq(messageReadContend.getAppId(),
                    messageRead.getFrom(), SeqConstants.CONVERSATION, seq);
        }
    }

    @Override
    public CommonResult deleteConversation(DeleteConversationReq req) {
        return null;
    }

    @Override
    public CommonResult updateConversation(UpdateConversationReq req) {
        if(req.getIsTop() == null && req.getIsMute() == null){
            return CommonResult.failed(ConversationErrorCode.CONVERSATION_UPDATE_PARAM_ERROR);
        }
        LambdaQueryWrapper<ImConversationSet> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImConversationSet::getConversationId, req.getConversationId());
        queryWrapper.eq(ImConversationSet::getAppId, req.getAppId());

        ImConversationSet imConversationSetEntity = baseMapper.selectOne(queryWrapper);
        if(imConversationSetEntity != null){
            long seq = redisSeq.doGetSeq(req.getAppId() + ":" + SeqConstants.CONVERSATION);

            if(req.getIsMute() != null){
                imConversationSetEntity.setIsTop(req.getIsTop());
            }
            if(req.getIsMute() != null){
                imConversationSetEntity.setIsMute(req.getIsMute());
            }
            imConversationSetEntity.setSequence(seq);
            baseMapper.update(imConversationSetEntity,queryWrapper);
            writeUserSeq.writeUserSeq(req.getAppId(), req.getFromId(),
                    SeqConstants.CONVERSATION, seq);

            // 更新会话通知
//            UpdateConversationPack pack = new UpdateConversationPack();
//            pack.setConversationId(req.getConversationId());
//            pack.setIsMute(imConversationSetEntity.getIsMute());
//            pack.setIsTop(imConversationSetEntity.getIsTop());
//            pack.setSequence(seq);
//            pack.setConversationType(imConversationSetEntity.getConversationType());
//            messageProducer.sendToUserExceptClient(req.getFromId(),
//                    ConversationEventCommand.CONVERSATION_UPDATE,
//                    pack,new ClientInfo(req.getAppId(),req.getClientType(),
//                            req.getImei()));
        }
        return CommonResult.success();
    }

    @Override
    public CommonResult<SyncResp<ImConversationSet>> syncConversationSet(SyncReq req) {
        if(req.getMaxLimit() > 100){
            req.setMaxLimit(100);
        }

        SyncResp<ImConversationSet> resp = new SyncResp<>();
        //seq > req.getseq limit maxLimit
        LambdaQueryWrapper<ImConversationSet> queryWrapper =
                new LambdaQueryWrapper<>();
        queryWrapper.eq(ImConversationSet::getFromId, req.getOperator());
        queryWrapper.gt(ImConversationSet::getSequence, req.getLastSequence());
        queryWrapper.eq(ImConversationSet::getAppId, req.getAppId());
        queryWrapper.last(" limit " + req.getMaxLimit());
        queryWrapper.orderByAsc(ImConversationSet::getSequence);
        List<ImConversationSet> list = baseMapper
                .selectList(queryWrapper);

        if(!CollectionUtils.isEmpty(list)){
            ImConversationSet maxSeqEntity = list.get(list.size() - 1);
            resp.setDataList(list);
            //设置最大seq
            Long friendShipMaxSeq = baseMapper.geConversationSetMaxSeq(req.getAppId(), req.getOperator());
            resp.setMaxSequence(friendShipMaxSeq);
            //设置是否拉取完毕
            resp.setCompleted(maxSeqEntity.getSequence() >= friendShipMaxSeq);
            return CommonResult.success(resp);
        }

        resp.setCompleted(true);
        return CommonResult.success(resp);
    }

    @Override
    public CommonResult addConversationSet(AddConversationSetReq addConversationSetReq) {
        LambdaQueryWrapper<ImConversationSet> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImConversationSet::getFromId, addConversationSetReq.getFromId());
        queryWrapper.eq(ImConversationSet::getToId, addConversationSetReq.getToId());
        queryWrapper.eq(ImConversationSet::getAppId, addConversationSetReq.getAppId());
        queryWrapper.eq(ImConversationSet::getConversationType, addConversationSetReq.getConversationType());

        ImConversationSet imConversationSetEntity = baseMapper.selectOne(queryWrapper);

        if (imConversationSetEntity == null) {
            long seq = redisSeq.doGetSeq(addConversationSetReq.getAppId() + ":" + SeqConstants.CONVERSATION);
            ImConversationSet imConversationSet = new ImConversationSet();
            BeanUtils.copyProperties(addConversationSetReq, imConversationSet);
            imConversationSet.setSequence(seq);
            // todo: id生成方案

            int insert = baseMapper.insert(imConversationSet);
            writeUserSeq.writeUserSeq(addConversationSetReq.getAppId(), addConversationSetReq.getFromId(),
                    SeqConstants.CONVERSATION, seq);

            return CommonResult.success(insert);
        }else {
            long seq = redisSeq.doGetSeq(addConversationSetReq.getAppId() + ":" + SeqConstants.CONVERSATION);

            imConversationSetEntity.setSequence(seq);

            baseMapper.updateById(imConversationSetEntity);
            writeUserSeq.writeUserSeq(addConversationSetReq.getAppId(), addConversationSetReq.getFromId(),
                    SeqConstants.CONVERSATION, seq);

            return CommonResult.success();
        }
    }


    /**
     * todo: 百分百需要优化的
     * @param pullConversationSet
     * @return
     */
    @Override
    public CommonResult<List<PullConversationSetResp>> pullConversationSet(PullConversationSet pullConversationSet) {
        LambdaQueryWrapper<ImConversationSet> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImConversationSet::getAppId, pullConversationSet.getAppId());
        queryWrapper.eq(ImConversationSet::getFromId, pullConversationSet.getOperator());

        queryWrapper.orderByDesc(ImConversationSet::getSequence);
        queryWrapper.last(" limit " + 30);

        List<ImConversationSet> imConversationSets = baseMapper.selectList(queryWrapper);

        List<PullConversationSetResp> objects = new ArrayList<>(30);

        imConversationSets.forEach(imConversationSet -> {
            if (imConversationSet.getConversationType() == ConversationTypeEnum.GROUP.getCode()) {
                CommonResult<ImGroup> group = imGroupService.getGroup(imConversationSet.getToId(), imConversationSet.getAppId());
                // 查最后一条数据
                CommonResult<LastMessageResp> groupLastMessage = imMessageHistoryService
                        .getUserLastMessage(imConversationSet.getFromId(), imConversationSet.getToId(), imConversationSet.getAppId());
                PullConversationSetResp pullConversationSetResp = new PullConversationSetResp();

                ImGroup data = group.getData();

                UserData userData = new UserData();
                userData.setUserId(data.getGroupId());
                userData.setPhoto(data.getPhoto());
                userData.setNickName(data.getGroupName());

                pullConversationSetResp.setData(userData);
                pullConversationSetResp.setLastMessage(groupLastMessage.getData());
                // 计算未读
                long unread = imConversationSet.getSequence() - imConversationSet.getReadedSequence();
                pullConversationSetResp.setUnread(unread);

                objects.add(pullConversationSetResp);
            }else {
                // 查头像
                CommonResult<ImUserData> singleUserInfo = imUserDataService
                        .getSingleUserInfo(imConversationSet.getToId(), imConversationSet.getAppId());
                // 查最后一条数据
                CommonResult<LastMessageResp> userLastMessage = imMessageHistoryService
                        .getUserLastMessage(imConversationSet.getFromId(), imConversationSet.getToId(), imConversationSet.getAppId());

                PullConversationSetResp pullConversationSetResp = new PullConversationSetResp();

                UserData userData = new UserData();
                BeanUtils.copyProperties(singleUserInfo.getData(), userData);

                pullConversationSetResp.setData(userData);
                // 计算未读
                long unread = imConversationSet.getSequence() - imConversationSet.getReadedSequence();
                pullConversationSetResp.setUnread(unread);

                pullConversationSetResp.setLastMessage(userLastMessage.getData());
                objects.add(pullConversationSetResp);
            }
        });



        return CommonResult.success(objects);
    }
}




